package tech.shupi.babytapmobile.util

import android.util.Log
import com.google.gson.Gson
import java.io.IOException
import java.security.cert.X509Certificate
import java.util.concurrent.TimeUnit
import javax.net.ssl.SSLContext
import javax.net.ssl.TrustManager
import javax.net.ssl.X509TrustManager
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response

class CardHttpClient {
    companion object {
        private const val TAG = "CardHttpClient"
        // 默认端口，实际端口由服务动态确定
        private const val DEFAULT_PORT = 8553
    }
    
    private var currentPort = DEFAULT_PORT
    private var baseUrl = "https://127.0.0.1:$DEFAULT_PORT"
    
    private val JSON = "application/json; charset=utf-8".toMediaType()
    private val mClient: OkHttpClient
    private val mGson = Gson()
    
    init {
        val trustAllCerts = arrayOf<TrustManager>(
            object : X509TrustManager {
                override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String) {}
                override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String) {}
                override fun getAcceptedIssuers(): Array<X509Certificate> = arrayOf()
            }
        )
        
        val builder = OkHttpClient.Builder()
            .connectTimeout(5, TimeUnit.SECONDS)
            .readTimeout(10, TimeUnit.SECONDS)
            .writeTimeout(10, TimeUnit.SECONDS)
        
        try {
            val sslContext = SSLContext.getInstance("TLS")
            sslContext.init(null, trustAllCerts, java.security.SecureRandom())
            builder.sslSocketFactory(sslContext.socketFactory, trustAllCerts[0] as X509TrustManager)
                .hostnameVerifier { _, _ -> true }
            Log.d(TAG, "SSL 客户端配置成功")
        } catch (e: Exception) {
            Log.e(TAG, "创建 SSL 客户端失败，使用普通 HTTP 客户端", e)
        }
        
        mClient = builder.build()
    }
    
    /**
     * 设置服务器端口
     */
    fun setPort(port: Int) {
        currentPort = port
        baseUrl = "https://127.0.0.1:$port"
        Log.d(TAG, "设置服务器端口: $port, 新的 baseUrl: $baseUrl")
    }
    
    /**
     * 获取当前端口
     */
    fun getCurrentPort(): Int {
        return currentPort
    }
    
    @Throws(IOException::class)
    fun getCards(): String {
        val url = "$baseUrl/api/cards"
        Log.d(TAG, "GET: $url")
        val request = Request.Builder()
            .url(url)
            .addHeader("Content-Type", "application/json")
            .build()
        Log.d(TAG, "即将请求: $url")
        val response = mClient.newCall(request).execute()
        Log.d(TAG, "请求完成: $url, code=${response.code}")
        return if (response.isSuccessful) {
            response.body?.string() ?: throw IOException("响应体为空")
        } else {
            throw IOException("获取卡片失败: ${response.code}")
        }
    }
    
    @Throws(IOException::class)
    fun createCard(json: String): String {
        val url = "$baseUrl/api/cards"
        Log.d(TAG, "POST: $url")
        val body = json.toRequestBody(JSON)
        val request = Request.Builder()
            .url(url)
            .post(body)
            .addHeader("Content-Type", "application/json")
            .build()
        Log.d(TAG, "即将请求: $url")
        val response = mClient.newCall(request).execute()
        Log.d(TAG, "请求完成: $url, code=${response.code}")
        return if (response.isSuccessful) {
            response.body?.string() ?: throw IOException("响应体为空")
        } else {
            throw IOException("创建卡片失败: ${response.code}")
        }
    }
    
    @Throws(IOException::class)
    fun updateCard(id: Int, json: String): String {
        val url = "$baseUrl/api/cards/$id"
        Log.d(TAG, "PUT: $url")
        val body = json.toRequestBody(JSON)
        val request = Request.Builder()
            .url(url)
            .put(body)
            .addHeader("Content-Type", "application/json")
            .build()
        Log.d(TAG, "即将请求: $url")
        val response = mClient.newCall(request).execute()
        Log.d(TAG, "请求完成: $url, code=${response.code}")
        return if (response.isSuccessful) {
            response.body?.string() ?: throw IOException("响应体为空")
        } else {
            throw IOException("更新卡片失败: ${response.code}")
        }
    }
    
    @Throws(IOException::class)
    fun deleteCard(id: Int): String {
        val url = "$baseUrl/api/cards/$id"
        Log.d(TAG, "DELETE: $url")
        val request = Request.Builder()
            .url(url)
            .delete()
            .addHeader("Content-Type", "application/json")
            .build()
        Log.d(TAG, "即将请求: $url")
        val response = mClient.newCall(request).execute()
        Log.d(TAG, "请求完成: $url, code=${response.code}")
        return if (response.isSuccessful) {
            response.body?.string() ?: throw IOException("响应体为空")
        } else {
            throw IOException("删除卡片失败: ${response.code}")
        }
    }
    
    @Throws(IOException::class)
    fun getHealth(): String {
        val url = "$baseUrl/health"
        Log.d(TAG, "GET: $url")
        val request = Request.Builder()
            .url(url)
            .addHeader("Content-Type", "application/json")
            .build()
        Log.d(TAG, "即将请求: $url")
        val response = mClient.newCall(request).execute()
        Log.d(TAG, "请求完成: $url, code=${response.code}")
        return if (response.isSuccessful) {
            response.body?.string() ?: throw IOException("响应体为空")
        } else {
            throw IOException("健康检查失败: ${response.code}")
        }
    }

    @Throws(IOException::class)
    fun sendUDPBroadcast(): String {
        val url = "$baseUrl/api/broadcast"
        Log.d(TAG, "POST: $url")
        val request = Request.Builder()
            .url(url)
            .post("".toRequestBody("application/json".toMediaType()))
            .addHeader("Content-Type", "application/json")
            .build()
        Log.d(TAG, "即将请求: $url")
        val response = mClient.newCall(request).execute()
        Log.d(TAG, "请求完成: $url, code=${response.code}")
        return if (response.isSuccessful) {
            response.body?.string() ?: throw IOException("响应体为空")
        } else {
            throw IOException("发送UDP广播失败: ${response.code}")
        }
    }

    @Throws(IOException::class)
    fun getDeviceName(): String {
        val url = "$baseUrl/api/device/name"
        Log.d(TAG, "GET: $url")
        val request = Request.Builder()
            .url(url)
            .addHeader("Content-Type", "application/json")
            .build()
        Log.d(TAG, "即将请求: $url")
        val response = mClient.newCall(request).execute()
        Log.d(TAG, "请求完成: $url, code=${response.code}")
        return if (response.isSuccessful) {
            response.body?.string() ?: throw IOException("响应体为空")
        } else {
            throw IOException("获取设备名称失败: ${response.code}")
        }
    }

    @Throws(IOException::class)
    fun setDeviceName(name: String): String {
        val url = "$baseUrl/api/device/name"
        Log.d(TAG, "PUT: $url")
        val jsonBody = "{\"name\":\"$name\"}"
        val body = jsonBody.toRequestBody(JSON)
        val request = Request.Builder()
            .url(url)
            .put(body)
            .addHeader("Content-Type", "application/json")
            .build()
        Log.d(TAG, "即将请求: $url")
        val response = mClient.newCall(request).execute()
        Log.d(TAG, "请求完成: $url, code=${response.code}")
        return if (response.isSuccessful) {
            response.body?.string() ?: throw IOException("响应体为空")
        } else {
            throw IOException("设置设备名称失败: ${response.code}")
        }
    }
} 